Repository navigation
ADFA-6381: Build one Kotlin library module per jar - #2108
Conversation
collectKtModules held the boot classpath as a lazy Sequence that called addLibrary, so every source module re-ran it and got a fresh KtLibraryModule for android.jar from each Android module: modules x Android-modules copies. Each copy materializes the jar's full file list for its search scope. GlitchTip breadcrumbs show the same android.jar scope built 55-71 times on large multi-module projects, behind 219 of 336 OOM events. addLibrary now reuses the module for a path, and the boot classpath is a distinct List, so each jar maps to exactly one module.
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review for a one-time review, or @claude review always to subscribe this PR to a review on every future push.
Tip: disable this comment in your organization's Code Review settings.
|
Important Review skippedReview was skipped as selected files did not have any reviewable changes. ⚙️ Run configuration
You can disable this status message by setting the Use the checkbox below for a quick retry:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
📒 Files selected for processing (3)
Included review availability: This review used your included allowance. 4 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 5 reviews per hour. 📝 Summary
Walkthrough
ChangesShared library modules
Priority: ⬇️ Low Estimated code review effort: 2 (Simple) | ~10 minutes Change: Bug fix Suggested reviewers: Merge Risk: ⚪ Minimal · up to The change is ready to merge after normal checks; no outstanding behavior issue was identified. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
A rabbit checks each jar in line Comment |
Now that addLibrary returns one shared KtLibraryModule per jar, a jar on both the boot classpath and a module's compile classpath was added to that module's dependencies twice as the same instance. Both module builders now keep dependencies in a LinkedHashSet: O(1) dedupe, order preserved. Tests: compile-classpath jars shared across modules resolve to one instance; a jar on both classpaths is one dependency (fails without the builder change: size 2).
ADFA-6381
The Kotlin LSP built a separate
KtLibraryModulefor every shared jar in every module, and each copy materializes the jar's full file list for its search scope. This is behind about 65% of GlitchTip OOM events (219 of 336), mostly on large multi-module projects.Cause
In
collectKtModules,bootClassPathswas a lazySequencewhose pipeline calledaddLibrary. Every source module re-ran it, so each one got a freshandroid.jarmodule from every Android module: modules x Android-modules copies.addLibraryalso never checkedjarToModMap, so a jar repeated across compile classpaths built a new module every time.Fix
addLibraryreturns the existing module for a path (getOrPut).distinct()List.KtSourceModule.BuilderandKtLibraryModule.Builderkeep dependencies in aLinkedHashSet, so a jar on both the boot and compile classpath is one dependency, not the same instance twice (O(1) per add, order kept).Verification
CollectKtModulesTest(3 Android modules sharing oneandroid.jar): fails on the old code (3 copies per module, expected 1), passes with the fix.CollectKtModulesTest, boot + compile classpath: fails without the builder change (size 2, expected 1).CollectKtModulesTest, compile-classpath jar shared by two modules resolves to one instance. This pins existing behavior: the per-pathlibraryDependenciesmap already shared it before this PR.:lsp:kotlin:testV8DebugUnitTest: 50 classes, 532 tests, 0 failures.:app+ 2 library modules), heap dump after project init:KtLibraryModuleinstancesKtSourceModuleinstancesdumpsys meminfo)The "before" build was an older stage build, so the heap figure is indicative; the instance counts come straight from this code path. Copies grow with modules x Android modules, so the saving is much larger on projects like TalkBack or media3.
android.*types (Context,TextView,android.widget.TextView::class) resolve with no diagnostics in both library modules.Siblings checked:
collectKtModulesis the only production caller ofbuildKtLibraryModule;libraryDependenciesnow shares modules through the samegetOrPut.No UI change, so no font-scale check.
Commits: the fix and test; a standalone Spotless reformat of
WorkspaceExts.kt; a standalone Spotless reformat of the two module builders; the builder dedupe and its tests.